<?php

namespace App\Http\Controllers\Admin;

use App\Models\Dining;
use App\Models\DiningReserve;
use App\Models\DiningReserveProd;
use App\Models\StoreRecord;
use App\Models\Transition;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

/**
 * @group 后台接口文档
 * @title 餐桌管理模块接口
 * @author chenke
 * @description 酒庄后台餐桌板块接口
 * @header name:X-Token type:string require:1 desc:登录令牌
 *  */
class Dini extends Base
{

    /**
     * @title 餐桌列表
     * @description 后台餐桌列表数据
     * @url /admin/dini/dinshow
     * @method GET
     * @module 餐桌板块
     * @author chenke
     * @param name:limit type:int require:1 default:1 other: desc:每页数据条数
     * @param name:page type:int require:1 default:1 other: desc:当前页数
     * @param name:timetype type:int require:1 default:1 desc:就餐时间段 other:(4个时间段,值只能是1,2,3,4中的一个)
     * @param name:searchcontent type:string require:0 default: other: desc:输入框搜索内容(对应餐桌英文名)
     * @return code:错误码
     * @return message:错误提示
     * @return data:餐桌数据@
     * @data id:餐桌ID title:餐桌英文名 title_zn:餐桌名 image:餐桌主图 sitnum:餐桌可坐人数 status:餐桌状态(0空桌1未到场2已到场3预定中) dinorder:预定信息@
     * @dinorder ordersn:订单编号 timetype:就餐时间段 pernum:预订人数 sitday:预定日期 contact:用户电话 username_zn:用户名称 status:订单状态
     */
    public function dinList(Request $request){
        $data = $request->all();
        $limit = $data['limit'];
        $page = $data['page'];
        $searchCont = (isset($data['searchcontent']) && $data['searchcontent'])?$data['searchcontent']:'';
        $startDate = (isset($data['startDate']) && $data['startDate'])?$data['startDate']:date('Y-m-d');
        $endDate = (isset($data['endDate']) && $data['endDate'])?$data['endDate']:date('Y-m-d');
        $timetype = (isset($data['timetype']) && $data['timetype'])?$data['timetype']:1;
        $where = [];
        if($searchCont){
            $where[] = ['title','like','%'.$searchCont.'%'];
        }
        $whereDates = [];
        if($endDate){
            $entime = strtotime($endDate) + 24*3600;
            $endDate = date('Y-m-d',$entime);
        }
        if($startDate && $endDate){
            $whereDates = [$startDate,$endDate];
        }
        $return = (new Dining())->getPageList(['limit'=>$limit,'page'=>$page,'timetype'=>$timetype],$where,$whereDates);
        return response()->json($return);
    }

    /**
     * @title 餐桌添加
     * @description 添加单个商品分类
     * @url /admin/dini/credin
     * @method POST
     * @module 餐桌板块
     * @author chenke
     * @param name:title type:string require:1 default: other: desc:餐桌英文名
     * @param name:title_zn type:string require:1 default: other: desc:商品分类中文名
     * @param name:image type:string require:1 default: other: desc:餐桌主图
     * @param name:sitnum type:int require:1 default:0 other: desc:餐桌位数
     * @return code:错误码
     * @return message:错误提示
     * @return data: 餐桌ID
     */
    public function dinAdd(Request $request){
        $data = $request->post();
        $rules = [
            'title'=>'required|string',
            'title_zn'=>'required|string',
            'image'=>'required|string',
            'sitnum'=>'required|integer'
        ];
        $messages = [
            'title.required'=> '请填写英文名',
            'title_zn.required'=> '请填写中文名',
            'image.required'=> '请上传图片',
            'sitnum.required'=> '请填写座位数',
            'sitnum.integer'=> '座位数数据格式错误'
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new Dining())->oneInsert($data);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'dinAdd');
        }
        return response()->json($result);
    }

    /**
     * @title 餐桌编辑
     * @description 编辑单个餐桌
     * @url /admin/dini/edtdin
     * @method POST
     * @module 餐桌板块
     * @author chenke
     * @param name:id type:int require:1 default:0 other: desc:餐桌ID
     * @param name:title type:string require:1 default: other: desc:餐桌英文名
     * @param name:title_zn type:string require:1 default: other: desc:餐桌中文名
     * @param name:image type:string require:1 default: other: desc:餐桌主图
     * @param name:sitnum type:int require:1 default:0 other: desc:餐桌位数
     * @return code:错误码
     * @return message:错误提示
     * @return data:餐桌ID
     */
    public function dinUpdate(Request $request){
        $data = $request->post();
        $rules = [
            'id'=>'required|integer',
            'title'=>'required|string',
            'title_zn'=>'required|string',
            'image'=>'required|string',
            'sitnum'=>'required|integer'
        ];
        $messages = [
            'id.required'=> '请选择餐桌',
            'id.integer'=> 'ID错误',
            'title.required'=> '请填写英文名',
            'title_zn.required'=> '请填写中文名',
            'image.required'=> '请上传图片',
            'sitnum.required'=> '请填写座位数',
            'sitnum.integer'=> '座位数数据格式错误'
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new Dining())->doUpdate($data);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'prodUpdate');
        }
        return response()->json($result);
    }

    /**
     * @title 预定订单列表
     * @description 获取餐厅预定订单列表
     * @url /admin/dini/dorshow
     * @method GET
     * @module 餐桌预定板块
     * @author chenke
     * @param name:limit type:int require:1 default:1 other: desc:每页数据条数
     * @param name:page type:int require:1 default:1 other: desc:当前页数
     * @param name:searchcontent type:string require:0 default: other: desc:输入框搜索内容(对应电话号码)
     * @param name:searchtype type:int require:0 default:0 other: desc:搜索时间类型(0为全部,1,2,3,4个时间段)
     * @param name:startDate type:date require:0 default: other: desc:搜索日期（开始日期,对应就餐日期）
     * @param name:endDate type:date require:0 default: other: desc:搜索日期（结束日期,对应就餐日期）
     * @return code:错误码
     * @return message:错误提示
     * @return data:预定基本信息@
     * @data id:预定ID ordersn:订单编号 ordtype:预定类型--1为预定2为现场点单 tid:餐桌ID title:餐桌英文名 title_zn:餐桌中文名 contact:用户电话 username:用户英文名 username_zn:用户中文名 uid:用户ID timetype:订餐时间类型 sitday:就餐日期 pernum:就餐人数 earnest:定金 total:应付总金额 status:预定状态0待付款1待接单2待进餐3待结账4已结账5退订6取消订单 created_at:预定时间
     */
    public function dinOrderList(Request $request){
        $data = $request->all();
        $limit = $data['limit'];
        $page = $data['page'];
        $searchCont = (isset($data['searchcontent']) && $data['searchcontent'])?$data['searchcontent']:'';
        $startDate = (isset($data['startDate']) && $data['startDate'])?$data['startDate']:'';
        $endDate = (isset($data['endDate']) && $data['endDate'])?$data['endDate']:'';
        $searchtype = (isset($data['searchtype']) && $data['searchtype'])?$data['searchtype']:0;
        $where = [];
        if($searchCont){
            $where[] = ['contact','like','%'.$searchCont.'%'];
        }
        if($searchtype){
            $where[] = ['timetype','=',$searchtype];
        }
        $whereDates = [];
        if($endDate){
            $entime = strtotime($endDate) + 24*3600;
            $endDate = date('Y-m-d',$entime);
        }
        if($startDate && $endDate){
            $whereDates = [$startDate,$endDate];
        }
        $return = (new DiningReserve())->getPageList(['limit'=>$limit,'page'=>$page],$where,$whereDates);
        return response()->json($return);
    }

    /**
     * @title 添加预定订单
     * @description 添加餐厅餐桌预定订单
     * @url /admin/dini/credor
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:tid type:int require:1 default: desc:餐桌ID other:
     * @param name:uid type:int require:1 default: desc:用户ID other:
     * @param name:timetype type:int require:1 default: desc:就餐时间段 other:(4个时间段,值只能是1,2,3,4中的一个)
     * @param name:sitday type:date require:1 default: odesc:就餐日期 ther:
     * @param name:pernum type:int require:1 default: desc:就餐人数 other:
     * @param name:remark type:string require:0 default: desc:订单备注 other:
     * @return code:错误码
     * @return message:错误提示
     * @return data:订单和交易信息@
     * @data id:订单ID
     */
    public function dinOrderAdd(Request $request){
        $data = $request->post();
        $rules = [
            'tid'=>'required|integer',
            'uid'=>'required|integer',
            'timetype'=>['required',Rule::in([1,2,3,4])],
            'sitday'=>'required|date',
            'pernum'=>'required|integer',
            'remark'=>'string',
        ];
        $messages = [
            'tid.required'=> '请传餐桌ID',
            'tid.integer'=> '餐桌ID错误',
            'uid.required'=> '请传用户ID',
            'uid.integer'=> '用户ID错误',
            'timetype.required'=> '请选择就餐时间',
            'timetype.in'=> '就餐时间错误',
            'sitday.required'=> '请选择就餐日期',
            'sitday.date'=> '就餐日错误',
            'pernum.required'=> '请选择就餐人数',
            'pernum.integer'=> '就餐人数错误'
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new DiningReserve())->oneInsert($data);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'dinOrderAdd');
        }
        return response()->json($result);
    }

    /**
     * @title 编辑预定订单
     * @description 编辑餐桌预定订单
     * @url /admin/dini/edtdor
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:id type:int require:1 default:0 desc:订单ID other:
     * @param name:tid type:int require:1 default:0 desc:餐桌ID other:
     * @param name:timetype type:int require:1 default:1 desc:就餐时间段 other:(4个时间段,值只能是1,2,3,4中的一个)
     * @param name:sitday type:date require:1 default: odesc:就餐日期 ther:
     * @param name:pernum type:int require:1 default: desc:就餐人数 other:
     * @param name:remark type:string require:0 default: desc:订单备注 other:
     * @return code:错误码
     * @return message:错误提示
     * @return data:订单ID
     */
    public function dinOrderEdit(Request $request){
        $data = $request->post();
        $rules = [
            'id'=>'required|integer',
            'tid'=>'required|integer',
            'timetype'=>['required',Rule::in([1,2,3,4])],
            'sitday'=>'required|date',
            'pernum'=>'required|integer',
            'remark'=>'string',
        ];
        $messages = [
            'id.required'=> '请传订单ID',
            'id.integer'=> '订单ID错误',
            'tid.required'=> '请传餐桌ID',
            'tid.integer'=> '餐桌ID错误',
            'timetype.required'=> '请选择就餐时间',
            'timetype.in'=> '就餐时间错误',
            'sitday.required'=> '请选择就餐日期',
            'sitday.date'=> '就餐日错误',
            'pernum.required'=> '请选择就餐人数',
            'pernum.integer'=> '就餐人数错误',
        ];
        $options = [
            'id'=>$data['id'],
            'tid'=>$data['tid'],
            'timetype'=>$data['timetype'],
            'sitday'=>$data['sitday'],
            'pernum'=>$data['pernum'],
        ];
        $options['remark'] = isset($data['remark'])?$data['remark']:' ';
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new DiningReserve())->doUpdate($options);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'dinOrderAdd');
        }
        return response()->json($result);
    }

    /**
     * @title 预定订单发起结账
     * @description 用于餐桌订单点击"结账"时返回结账信息
     * @url /admin/dini/dorchk
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:id type:int require:1 default:0 desc:预定订单ID other:
     * @return code:错误码
     * @return message:错误提示
     * @return data:结账交易信息@
     * @data id:交易单ID number:应付金额 paytype:支付方式(1为钱包支付、2为反馈钱包支付、3为现金支付、4提现;默认为1) transno:交易单号 balance:用户当前余额 cycle_balance:用户当前反馈钱包余额 uid:用户ID status:交易状态(1待交易2成功3失败4取消)
     */
    public function dinOrderCheckOut(Request $request){
        $id = $request->post('id');
        if(!$id){
            return response()->json(['code'=>1,'message'=>'参数错误']);
        }
        $return = (new DiningReserve())->orderCheckOut($id);
        if($return['code']){
            $this->logErr($return['code'],$return['message'],'dinOrderCheckOut');
        }
        return  response()->json($return);
    }

    /**
     * @title 预定订单确认结账
     * @description 用于餐桌订单确认结账
     * @url /admin/dini/dorsel
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:sign type:string require:1 default:0 desc:交易签名数据 other:签名字段包含支付方式(paytype)、含交易单号(transno)、含过期时间(expired)、应付金额(number)、优惠金额(youhui)
     * @return code:错误码
     * @return message:错误提示
     * @return data:结账交易信息@
     * @data transno:交易单号 number:交易金额
     */
    public function dinOrderSettle(Request $request){
        $sign = $request->post('sign');
        if(!$sign){
            return response()->json(['code'=>1,'message'=>'参数错误']);
        }
        $signData = $this->decreSign($sign);
        if($signData['code']){
            return  response()->json($signData);
        }
        $return = (new DiningReserve())->orderSettle($signData['data']);
        if($return['code']){
            $this->logErr($return['code'],$return['message'],'dinOrderSettle');
        }
        return  response()->json($return);
    }

    /**
     * @title 预定订单状态改变
     * @description 用于预定订单接单、进场
     * @url /admin/dini/dorset
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:id type:int require:1 default:0 desc:预定订单ID other:
     * @param name:status type:int require:1 default: desc:需要变成的值 other:(2个操作,值只能是2,3中的一个)
     * @return code:错误码
     * @return message:错误提示
     * @return data:订单ID
     */
    public function dinOrderChangeStatus(Request $request){
        $data = $request->post();
        $rules = [
            'id'=>'required|integer',
            'status'=>[
                'required',Rule::in([2,3])
            ]
        ];
        $messages = [
            'id.required'=> '请传预定ID',
            'id.integer'=> '预定ID错误',
            'status.required'=> '请传状态参数',
            'status.in'=> '状态参数错误'
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new DiningReserve())->changeStatus($data);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'dinOrderChangeStatus');
        }
        return response()->json($result);
    }

    /**
     * @title 预定订单详情
     * @description 获取餐桌预定的商品信息
     * @url /admin/dini/dordetail
     * @method GET
     * @module 餐桌预定板块
     * @author chenke
     * @param name:id type:int require:1 default:0 other: desc:预定订单ID
     * @return code:错误码
     * @return message:错误提示
     * @return data:预定详细信息@
     * @data id:商品订单ID did:餐桌预定ID proid:商品ID ordersn:订单编号 proname:商品英文名 proname_zn:商品中文名 image:商品主图 proprice:商品成交价格 pronum:商品成交数量 status:商品成交状态 created_at:商品添加时间
     */
    public function getDiningOrderDetail(Request $request){
        $orderid = $request->get('id');
        if(!$orderid){
            return response()->json(['code'=>1,'message'=>'参数错误']);
        }
        $return = (new DiningReserveProd())->getProdDetails($orderid);
        if($return['code']){
            $this->logErr($return['code'],$return['message'],'getDiningOrderDetail');
        }
        return  response()->json($return);
    }

    /**
     * @title 餐桌预定订单商品添加
     * @description 添加餐桌预定订单商品
     * @url /admin/dini/credorp
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:did type:int require:1 default: other: desc:预定订单ID
     * @param name:prods type:json require:1 default: other: desc:商品信息[{proid:1,pronum:2,status:2}].proid(商品ID)pronum(商品数量)status(订单状态2待付款,3已付款)
     * @return code:错误码
     * @return message:错误提示
     * @return data:正确时返回为空
     */
    public function addDinOrderProd(Request $request){
        $data = $request->post();
        $rules = [
            'did'=>'required|integer',
            'prods'=>'required|json'
        ];
        $messages = [
            'did.required'=> '请传订单ID',
            'did.integer'=> '订单ID错误',
            'prods.required'=> '请传商品信息',
            'prods.json'=> '商品信息数据格式错误',
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new DiningReserveProd())->oneInsert($data,"admin");
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'addDinOrderProd');
        }
        return response()->json($result);
    }

    /**
     * @title 餐桌预定订单商品存储
     * @description 餐桌预定订单商品存储
     * @url /admin/dini/store
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:did type:int require:1 default: other: desc:预定订单ID
     * @param name:proid type:int require:1 default: other: desc:商品ID
     * @param name:number type:int require:1 default: other: desc:商品数量
     * @return code:错误码
     * @return message:错误提示
     * @return data:正确时返回为空
     */
    public function dinOrderProdStore(Request $request){
        try {
            $data = $request->post();
            $rules = [
                'did'=>'required|integer',
                'proid'=>'required|integer',
                'number'=>'required|integer',
            ];
            $messages = [
                'did.required'=> '请传订单ID',
                'did.integer'=> '订单ID错误',
                'proid.required'=> '请传商品ID',
                'proid.integer'=> '商品ID格式错误',
                'number.required'=> '请传商品存储数量',
                'number.integer'=> '商品存储数量格式错误',
            ];
            $check = $this->checkParams($data,$rules,$messages);
            if($check['code']){
                return response()->json($check);
            }
            $din = DiningReserve::find($data['did']);
            $data['uid'] = $din->uid;
            unset($data['did']);
            $data['created_at'] = date('Y-m-d H:i:s');
            $data['updated_at'] = date('Y-m-d H:i:s');
            $id =  (new StoreRecord())->insertGetId($data,"admin");
            if($id){
                return response()->json([
                    'code'=>0,
                    'data'=>''
                ]);
            }else{
                return response()->json([
                    'code'=>1,
                    'message'=>'存储失败'
                ]);
            }
        }catch (\Exception $e){
            $this->logErr($e->getCode(),$e->getMessage(),'dinOrderProdStore');
            return response()->json([
                'code'=>0,
                'message'=>$e->getMessage()
            ]);
        }
    }

    /**
     * @title 餐桌预定订单商品退订
     * @description 添加餐桌预定订单商品退订
     * @url /admin/dini/deldorp
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:id type:int require:1 default: other: desc:商品订单ID
     * @return code:错误码
     * @return message:错误提示
     * @return data:正确时为空
     */
    public function delDinOrderProd(Request $request){
        $data = $request->post();
        $rules = [
            'id'=>'required|integer'
        ];
        $messages = [
            'id.required'=> '请传商品订单ID',
            'id.integer'=> '商品订单ID错误',
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        //退订订单商品
        $result =  (new DiningReserveProd())->oneDelete($data['id']);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'addDinOrderProd');
        }
        return response()->json($result);
    }

    /**
     * @title 确认支付/取消订单(预定订单)
     * @description 餐厅预定订单订金或结账进行确认支付或支付取消
     * @url /admin/dini/dopay
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:did type:int require:1 default: other: desc:订单ID
     * @param name:transtype type:int require:1 default: other:(1为预定订单订金、2为预定订单结账) desc:交易类型(预订方式为现场点餐则无类型1)
     * @param name:paytype type:int require:1 default: other:(1为钱包支付、2为反馈钱包支付、3为现金支付) desc:支付类型
     * @param name:dotype type:int require:1 default: other:(1确认支付2取消订单) desc:操作类型
     * @param name:decre type:int require:0 default: other: desc:支付优惠金额(确定支付时有才传该参数)
     * @return code:错误码
     * @return message:错误提示
     * @return data:操作成功时为空
     */
    public function confirmPay(Request $request){
        $data = $request->post();
        $rules = [
            'did'=>'required|integer',
            'paytype'=>['required',Rule::in([1,2,3])],
            'dotype'=>['required',Rule::in([1,2,3])],
            'transtype'=>['required',Rule::in([1,2])],
            'decre'=>'integer'
        ];
        $messages = [
            'did.required'=> '请传订单ID',
            'did.integer'=> '订单ID错误',
            'transtype.required'=> '请选择交易类型',
            'transtype.in'=> '交易类型错误',
            'paytype.required'=> '请选择支付类型',
            'paytype.in'=> '支付类型错误',
            'dotype.required'=> '请明确操作类型',
            'dotype.in'=> '操作类型错误',
            'decre.integer'=> '优惠金额错误',
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new Transition())->dinOrdPay($data);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'addDinOrderProd');
        }
        return response()->json($result);
    }

    /**
     * @title 预定订单退订
     * @description 餐厅预定订单退订退款
     * @url /admin/dini/reford
     * @method POST
     * @module 餐桌预定板块
     * @author chenke
     * @param name:did type:int require:1 default: other: desc:订单ID
     * @param name:number type:int require:1 default: other: desc:退款金额
     * @param name:paytype type:int require: default: other: desc:退款方式(1退款到钱包,2现金退款)
     * @return code:错误码
     * @return message:错误提示
     * @return data:操作成功时为空
     */
    public function refundDinOrd(Request $request){
        $data = $request->post();
        $rules = [
            'did'=>'required|integer',
            'number'=>'required|integer',
            'paytype'=>[
                'integer',Rule::in([1,2])
            ]
        ];
        $messages = [
            'did.required'=> '请传订单ID',
            'did.integer'=> '订单ID错误',
            'number.required'=> '退款金额必须',
            'number.integer'=> '退款金额错误',
            'paytype.in'=> '退款方式错误'
        ];
        $check = $this->checkParams($data,$rules,$messages);
        if($check['code']){
            return response()->json($check);
        }
        $result =  (new Transition())->dinOrdRefund($data);
        if($result['code']){
            $this->logErr($result['code'],$result['message'],'addDinOrderProd');
        }
        return response()->json($result);
    }
}
